﻿using System;
using System.Collections.Generic;
using System.Linq;
using TimetableCSP.Scheduler.Entities;

namespace TimetableCSP.Scheduler
{
	/// <summary>
	/// Contains information about a change made during an iteration of the Min-conflicts algorithm.
	/// </summary>
	public class Change
	{
		/// <summary>
		/// The variable that was changed
		/// </summary>
		public AbstractVariable Variable;

		/// <summary>
		/// The attribute that was changed
		/// </summary>
		public string Attribute = "";

		/// <summary>
		/// The original attribute value.
		/// </summary>
		public int OriginalValue;  //We need a string representation of this too

		/// <summary>
		/// The modified attribute value.
		/// </summary>
		public int ModifiedValue;  //We need a string representation of this too

		/// <summary>
		/// The number of conflicts caused by the variable before the change.
		/// </summary>
		public int OriginalConflictCount;

		/// <summary>
		/// The number of conflicts caused by the variable after the change.
		/// </summary>
		public int ModifiedConflictCount;

		/// <summary>
		/// Constructs a textual change report.
		/// </summary>
		/// <param name="changeHistory">A list of all the changes made.</param>
		/// <returns>A change log/report.</returns>
		public static string ChangeHistoryToString(List<Change> changeHistory)
		{
			const int outputHeadersEveryXIterations = 30;

			const string iteration = "Iteration";
			const string course = "CourseAndClass                  ";
			const string attribute = "Attribute   ";
			const string originalValue = "OriginalValue       ";
			const string modifiedValue = "ModifiedValue       ";
			const string originalConflictCount = "OriginalConflicts";
			const string modifiedConflictCount = "ModifiedConflicts";
			const string boundary = " | ";

			string output = "\nChange history\n\n";

			Classroom[] classrooms = DataProvider.GetClassrooms().ToArray();

			string originalValueString, modifiedValueString, courseAndClass;
			ClassVariable currClass;
			for (int index = 0; index < changeHistory.Count; ++index)
			{
				Change current = changeHistory[index];
				if (index == 0 || (index % outputHeadersEveryXIterations) == 0)
				{ 
					output += iteration + " " + course + " " + attribute + " " + originalValue + " " + modifiedValue + " " + originalConflictCount + " " + modifiedConflictCount + Environment.NewLine;
				}

				output += Convert.ToString(index + 1).PadLeft((iteration.Length + 1) - boundary.Length) + boundary;
				
				currClass = (ClassVariable)current.Variable;
				courseAndClass = currClass.CourseId + " - " + currClass.Name;
				output += courseAndClass.PadRight((course.Length + 1 ) - boundary.Length) + boundary;

				output += current.Attribute.PadRight((attribute.Length + 1 ) - boundary.Length) + boundary;
				if (current.Attribute == ClassVariable.ClassroomAttributeName)
				{
					originalValueString = classrooms[current.OriginalValue].Name;
					modifiedValueString = classrooms[current.ModifiedValue].Name;
				}
				else
				{ 
					originalValueString = Convert.ToString(current.OriginalValue);
					modifiedValueString = Convert.ToString(current.ModifiedValue);
				}
				output += originalValueString.PadLeft((originalValue.Length + 1) - boundary.Length) + boundary;
				output += modifiedValueString.PadLeft((modifiedValue.Length + 1) - boundary.Length) + boundary;
				
				output += Convert.ToString(current.OriginalConflictCount).PadLeft((originalConflictCount.Length + 1) - boundary.Length) + boundary;
				output += Convert.ToString(current.ModifiedConflictCount).PadLeft((modifiedConflictCount.Length + 1) - boundary.Length) + boundary;

				output += Environment.NewLine;
			}

			return output;
		}
	}
}